package routes

import (
	"deployment-service/domain"
	"deployment-service/jenkins"
	"deployment-service/jenkins/impl"
	"deployment-service/utils"
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
)

/**
  获取job信息，判断job是否存在
 */
func GetJenkinsJob(c *gin.Context)  {

	var reqData domain.JenkinsJobEntity
	if err := c.ShouldBindJSON(&reqData); err != nil {
		HandleError(http.StatusBadRequest, c, err)
		return
	}

	_, err := getJenkinsJob(reqData)
	existed := err == nil

	c.JSON(http.StatusOK, Response{
		Status:  "ok",
		Message: "success",
		Data:  existed,
	})
}

/**
   获取job的最后编译结果是否成功
 */
func GetJenkinsJobLastBuild(c *gin.Context)  {

	var reqData domain.JenkinsJobEntity
	if err := c.ShouldBindJSON(&reqData); err != nil {
		HandleError(http.StatusBadRequest, c, err)
		return
	}

	job, err := getJenkinsJob(reqData)
	if err != nil {
		HandleError(http.StatusBadRequest, c,
			fmt.Errorf("job不存在: %s", reqData.JobName))
	}

	lastBuild, err := job.GetLastBuild()
	if err != nil {
		HandleError(http.StatusBadRequest, c,
			fmt.Errorf("获取job: %s的最后编译信息失败: %v", reqData.JobName, err))
		return
	}

	result := lastBuild.GetResult()
	success := "SUCCESS" == result
	c.JSON(http.StatusOK, Response{
		Status:  "ok",
		Message: "success",
		Data:    success,
	})
}

func BuildJenkinsJob(c *gin.Context) {
	var reqData domain.JenkinsBuildJobEntity
	if err := c.ShouldBindJSON(&reqData); err != nil {
		HandleError(http.StatusBadRequest, c, err)
		return
	}

	job, err := getJenkinsJob(reqData.JenkinsJobEntity)
	if err != nil {
		HandleError(http.StatusBadRequest, c,
			fmt.Errorf("job不存在: %s", reqData.JobName))
		return
	}

	buildParams, err := utils.Str2Map(reqData.Params)
	if err != nil {
		HandleError(http.StatusBadRequest, c,
			fmt.Errorf("参数必须为json格式: %s", reqData.Params))
		return
	}

	queueId, err := job.Build(buildParams)
	if err != nil {
		HandleError(http.StatusBadRequest, c,
			fmt.Errorf("构建错误: %s", err))
		return
	}

	c.JSON(http.StatusOK, Response{
		Status:  "ok",
		Message: "success",
		Data:    queueId,
	})
}

/**
  获取build日志
*/
func GetJenkinsBuildLog(c *gin.Context) {
	var reqData domain.JenkinsBuildJobResultEntity
	if err := c.ShouldBindJSON(&reqData); err != nil {
		HandleError(http.StatusBadRequest, c, err)
		return
	}

	job, err := getJenkinsJob(reqData.JenkinsJobEntity)
	if err != nil {
		HandleError(http.StatusBadRequest, c,
			fmt.Errorf("job不存在: %s", reqData.JobName))
		return
	}

	jenkinsBuild, err := job.GetBuildFromQueueID(reqData.QueueId)
	if err != nil {
		HandleError(http.StatusBadRequest, c,
			fmt.Errorf("获取job的编译结果失败: %s", reqData.JobName))
		return
	}

	output := jenkinsBuild.GetConsoleOutput()
	c.JSON(http.StatusOK, Response{
		Status:  "ok",
		Message: "success",
		Data:    output,
	})
}

/**
  获取build结果
 */
func GetJenkinsBuildResult(c *gin.Context) {
	var reqData domain.JenkinsBuildJobResultEntity
	if err := c.ShouldBindJSON(&reqData); err != nil {
		HandleError(http.StatusBadRequest, c, err)
		return
	}

	job, err := getJenkinsJob(reqData.JenkinsJobEntity)
	if err != nil {
		HandleError(http.StatusBadRequest, c,
			fmt.Errorf("job不存在: %s", reqData.JobName))
		return
	}

	build, err := job.GetBuildFromQueueID(reqData.QueueId)
	if err != nil {
		HandleError(http.StatusBadRequest, c,
			fmt.Errorf("获取job的编译结果失败: %s", reqData.JobName))
		return
	}

	// FAILURE SUCCESS
	c.JSON(http.StatusOK, Response{
		Status:  "ok",
		Message: "success",
		Data:    build.GetResult(),
	})
}

/**
  创建job
*/
func CreateJenkinsJob(c *gin.Context) {
	var reqData domain.JenkinsCreateJobEntity
	if err := c.ShouldBindJSON(&reqData); err != nil {
		HandleError(http.StatusBadRequest, c, err)
		return
	}

	jenkinsEntity := &reqData.JenkinsEntity
	jenkins := impl.NewJenkins(jenkinsEntity)

	coder := utils.Coder{}
	jobContent, err := coder.Decode(reqData.JobContent)
	if err != nil {
		HandleError(http.StatusBadRequest, c, err)
		return
	}
	_, err = jenkins.CreateJob(reqData.JobName, jobContent)
	if err != nil {
		HandleError(http.StatusBadRequest, c, err)
		return
	}

	c.JSON(http.StatusOK, Response{
		Status:  "ok",
		Message: "success",
		Data:    "",
	})

}

func getJenkinsJob(reqData domain.JenkinsJobEntity) (jenkins.IJenkinsJob, error) {
	jobName := reqData.JobName

	jenkinsEntity := &reqData.JenkinsEntity
	jenkins := impl.NewJenkins(jenkinsEntity)

	job, err := jenkins.GetJob(jobName)
	if err != nil {
		return nil, err
	}
	return job, nil
}